package cn.yunyichina.provider.base.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import cn.yunyichina.provider.base.dao.OrgAppDao;
import cn.yunyichina.provider.base.dao.OrgAppDevelopDao;
import cn.yunyichina.provider.base.dao.OrgDao;
import cn.yunyichina.provider.base.dao.OrgSettingDao;
import cn.yunyichina.provider.base.entity.OrgAppDevelop;
import cn.yunyichina.provider.base.service.OrgService;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.page.PageInfo;
import cn.yunyichina.provider.iface.entity.base.BranchOutVo;
import cn.yunyichina.provider.iface.entity.base.HospitalOutVo;
import cn.yunyichina.provider.iface.entity.base.Org;
import cn.yunyichina.provider.iface.entity.base.OrgApp;
import cn.yunyichina.provider.iface.entity.base.OrgSettingVo;
import cn.yunyichina.provider.iface.entity.base.OrgSettingVoResponse;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.utils.convert.JsonUtils;

/**
 * Created by JoeZ on 2016/10/31.
 */
@Service
public class OrgServiceImpl implements OrgService {

    @Autowired
    private OrgDao orgDao;

    @Autowired
    private OrgAppDao orgAppDao;

    @Autowired
    private OrgAppDevelopDao orgAppDevelopDao;

    @Autowired
    private OrgSettingDao orgSettingDao;

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static Logger log = LoggerFactory.getLogger(OrgServiceImpl.class);

    /**
     * 查询可用组织
     * @param data
     * @interfaceName: yyt.base.org.usable.get
     * @return
     */
    public Response getOrgUsable(String data) {

        Response response = new Response();
        Org org = new Org();
        org.setEnableFlag((short)1);
        List<Org> orgs = orgDao.select(org);
        response.setResult(JsonUtils.toJsonString(orgs));
        response.setResultCodeAndMessage("0", "查询成功!");

        return response;

    }


    /**
     * 获取组织可用应用
     * @param data
     * @interfaceName: yyt.base.org.app.get
     * @return
     */
    public Response getOrgApp(String data) {

        Response response = new Response();
        OrgApp orgApp = JsonUtils.parseObject(data, OrgApp.class);
        List<OrgApp> select = orgAppDao.select(orgApp);
        if(select.size() > 0){
            response.setResult(JsonUtils.toJsonString(select));
            response.setResultCodeAndMessage(Response.SUCCESS_CODE, Response.SUCCESS_MESSAGE);
        }else{
            response.setResult(null);
            response.setResultCodeAndMessage(Response.FAILURE_CODE, Response.FAILURE_MESSAGE);
        }

        return response;

    }



    /**
     * 查询该组织下所有机构
     * @param data
     * @return
     */
    public Response getOrgAppDevelopList(String data) {
        Response response = new Response();
        String orgId  = data;
        OrgAppDevelop develop = new OrgAppDevelop();
        develop.setDevOrgId(orgId);
        List<OrgAppDevelop> develops = orgAppDevelopDao.select(develop);
        if(develops.size() > 0){
            response.setResult(JsonUtils.toJsonString(develops));
            response.setResultCodeAndMessage("0", "查询成功!");
        }else{
            response.setResult(null);
            response.setResultCodeAndMessage("10001", "查询失败!");
        }

        return response;

    }

    /**
     * 根据code查询Org
     * <br>内部调用接口
     * @param orgCode
     * @return 如果查询到1个，返回Org对象，如果没有找到或多于1个，返回null
     */
    public Org getOrgByCode(String orgCode) {
    	
    	Org org = new Org();
    	org.setOrgCode(orgCode);
        List<Org> listOrg = orgDao.select(org);
        if (listOrg != null && listOrg.size() ==1) {
        	return listOrg.get(0);
        }
        return null;

    }

    /**
     * 根据id查询org组织<br>
     * yyt.base.org.by.id.find
     * @param orgId
     * @return
     */
    public Response findOrgById(String orgId) {
    	if (orgId.startsWith("{")) {
    		JSONObject param = JsonUtils.parseObject(orgId);
    		orgId = param.getString("id");
    		if (StringUtils.isBlank(orgId)) {
    			orgId = param.getString("org_id");
    		}
    	}
        Response response = new Response();
        Org org = orgDao.selectById(orgId);

        response.setResult(JsonUtils.toJsonString(org));
        response.setResultCodeAndMessage("0", "查询成功!");
        return response;

    }


    /**
     * 组织信息列表查询
     * @param data(可根据：组织名称、组织类型、是否禁用标志进行查询，查询字段可继续扩展。当page_num和page_size为空时表示不分页返回所有数据)
     * @return
     * @author CJun
     */
    public Response listOrg(String data) {
        //定义返回结果
        Response response = new Response();
        Map<String, Object> result = new HashMap<>();

        //定义返回列表和分页信息
        List<Org> list = null;
        PageInfo pageInfo = new PageInfo();

        //定义返回码和返回信息
        String resultCode = "1000";
        String resultMessage = "执行成功";

        try {
            //获取入参
            log.info("【组织信息列表查询】开始, 入参->"+data);
            Org orgVo = JsonUtils.parseObject(data, Org.class);
            Map<String, String> maps = JsonUtils.parseObject(data, Map.class);
            String pageNum = maps.get("page_num");
            String pageSize = maps.get("page_size");

            //查询，如需分页则计算分页信息
            if(StringUtils.isNotBlank(pageNum) && StringUtils.isNotBlank(pageSize)){
                long count = orgDao.selectCount(orgVo);
                pageInfo.setTotal(count);
                pageInfo.setPageNum(Integer.valueOf(pageNum));
                pageInfo.setPageSize(Integer.valueOf(pageSize));
                pageInfo.setPages((pageInfo.getTotal().intValue() + pageInfo.getPageSize() - 1) / pageInfo.getPageSize());
                list = orgDao.select(orgVo , pageInfo);
            }else if(StringUtils.isBlank(pageNum) && StringUtils.isBlank(pageSize)){
                list = orgDao.select(orgVo);
            }else{
                resultCode = "1001";
                resultMessage = "参数有误:" + "page_num不能为空或者page_size不能为空";
            }
        } catch (Exception e) {
            resultCode = "1999";
            resultMessage = "系统异常:" + e.getMessage();
            e.printStackTrace();
        } finally {
            //组装返回结果
            result.put("list" , list);
            result.put("page_info" , pageInfo);
            response.setResult(JsonUtils.toJsonString(result));
            response.setResultCodeAndMessage(resultCode, resultMessage);
            log.info("【组织信息列表查询】结束, " + resultCode + ", " + resultMessage);
            return response;
        }
    }

    /**
     * 保存组织信息
     * @param data
     * @return
     * @author CJun
     */
    public Response saveOrg(String data) {

        //定义入参
        Org  orgVo = new Org();

        //定义返回结果
        Response response = new Response();

        //定义返回码和返回信息
        String resultCode = "1000";
        String resultMessage = "执行成功";

        try {
            //获取入参
            log.info("【修改组织信息】开始, 入参->"+data);
            orgVo = JsonUtils.parseObject(data, Org.class);

            //检查参数合法性
            boolean check = true;
            if(StringUtils.isBlank(orgVo.getOrgCode())){
                check = false;
                resultCode = "1001";
                resultMessage = "参数有误:" + "org_code不能为空";
            }else if(StringUtils.isBlank(orgVo.getOrgName())){
                check = false;
                resultCode = "1001";
                resultMessage = "参数有误:" + "org_name不能为空";
            }else if(orgVo.getOrgType() == null){
                check = false;
                resultCode = "1001";
                resultMessage = "参数有误:" + "org_type不能为空";
            }else if(orgVo.getEnableFlag() == null){
                check = false;
                resultCode = "1001";
                resultMessage = "参数有误:" + "enable_flag不能为空";
            }else{
                //查询是否存在相同编号的组织信息
                Org orgCheck = new Org();
                orgCheck.setOrgCode(orgVo.getOrgCode());
                List<Org> list = orgDao.select(orgCheck);
                if(list != null && list.size() > 0){
                    if(!list.get(0).getId().equals(orgVo.getId())){
                        check = false;
                        resultCode = "1003";
                        resultMessage = "存在重复信息:" + "该编码已存在";
                    }
                }
            }

            //检查不通过，结束流程
            if(!check){
                return response;
            }

            //参数组装
            if(StringUtils.isBlank(orgVo.getId())){
                //新增
                orgVo.setId(PKGenerator.generateId());
                orgVo.setCreatedTime(simpleDateFormat.format(new Date()));
                orgVo.setUpdateTime(simpleDateFormat.format(new Date()));
                orgDao.insert(orgVo);
            }else{
                //更新
                orgVo.setUpdateTime(simpleDateFormat.format(new Date()));
                orgDao.update(orgVo);
            }
        } catch (NumberFormatException e) {
            resultCode = "1999";
            resultMessage = "系统异常:" + e.getMessage();
            e.printStackTrace();
        } finally {
            //组装返回结果
            response.setResultCodeAndMessage(resultCode, resultMessage);
            log.info("【修改组织信息】结束, " + resultCode + ", " + resultMessage);
            return response;
        }
    }

    /**
     * 组织配置信息列表查询
     * @param data(可根据：医院编号、分院编号、方法名称，查询字段可继续扩展)
     * @return
     * @author CJun
     */
    public Response listOrgsetting(String data) {
        //定义返回结果
        Response response = new Response();
        Map<String, Object> result = new HashMap<>();

        //定义返回列表和分页信息
        List<OrgSettingVoResponse> list = null;

        //定义返回码和返回信息
        String resultCode = "0";
        String resultMessage = "执行成功";

        try {
            //获取入参
            log.info("【组织配置信息列表查询】开始, 入参->"+data);
            OrgSettingVo orgSettingVo = JsonUtils.parseObject(data, OrgSettingVo.class);

            //检查参数合法性
            boolean check = true;
            if(StringUtils.isBlank(orgSettingVo.getHospitalCode())){
                check = false;
                resultCode = "1001";
                resultMessage = "参数有误:" + "hospital_code不能为空";
            }

            //检查不通过，结束流程
            if(!check){
                return response;
            }

            //查询
            if(StringUtils.isBlank(orgSettingVo.getMethodCode())){
                list = this.querySettingByNoMethod(orgSettingVo);
            }else{
                if(StringUtils.isBlank(orgSettingVo.getBranchCode())){
                    list = orgSettingDao.getOrgSettingListByMethodCode(orgSettingVo.getHospitalCode(), orgSettingVo.getHospitalCode(), orgSettingVo.getMethodCode());
                    log.info("【组织配置信息列表有method查询】, Method=" + orgSettingVo.getMethodCode() +" HospitalCode=" + orgSettingVo.getHospitalCode() + ",查询结果list=" + JsonUtils.toJsonString(list));
                }else{
                    list = orgSettingDao.getOrgSettingListByMethodCode(orgSettingVo.getBranchCode(), orgSettingVo.getHospitalCode(), orgSettingVo.getMethodCode());
                    log.info("【组织配置信息列表有method查询】, Method=" + orgSettingVo.getMethodCode() +", BranchCode=" + orgSettingVo.getBranchCode() +" HospitalCode=" + orgSettingVo.getHospitalCode() + ",查询结果list=" + JsonUtils.toJsonString(list));
                    //如果根据分院查询不到信息，则用总院去查询
                    if(list != null && list.size() == 0){
                        log.info("【组织配置信息列表有method查询】, 根据分院查询不到信息, 开始往总院查询");
                        list = orgSettingDao.getOrgSettingListByMethodCode(orgSettingVo.getHospitalCode(), orgSettingVo.getHospitalCode(), orgSettingVo.getMethodCode());
                        log.info("【组织配置信息列表有method查询】, Method=" + orgSettingVo.getMethodCode() +" HospitalCode=" + orgSettingVo.getHospitalCode() + ",查询结果list=" + JsonUtils.toJsonString(list));
                    }
                }

                //如果带方法的情况下查询不到数据，则调用不带方法的查询
                if(list != null && list.size() == 0){
                    log.info("【组织配置信息列表有method查询】, 根据method查询不到信息, 开始往无method查询");
                    list = this.querySettingByNoMethod(orgSettingVo);
                }
            }
        } catch (Exception e) {
            resultCode = "1999";
            resultMessage = "系统异常:" + e.getMessage();
            e.printStackTrace();
        } finally {
            //组装返回结果
            response.setResult(JsonUtils.toJsonString(list));
            response.setResultCodeAndMessage(resultCode, resultMessage);
            log.info("【组织配置信息列表查询】结束, " + resultCode + ", " + resultMessage);
            return response;
        }
    }

    public List<OrgSettingVoResponse> querySettingByNoMethod(OrgSettingVo orgSettingVo){
        List<OrgSettingVoResponse> list = null;

        if(StringUtils.isBlank(orgSettingVo.getBranchCode())){
            list = orgSettingDao.getOrgSettingList(orgSettingVo.getHospitalCode(), orgSettingVo.getHospitalCode());
            log.info("【组织配置信息列表无method查询】, HospitalCode=" + orgSettingVo.getHospitalCode() + ",查询结果list=" + JsonUtils.toJsonString(list));
        }else{
            list = orgSettingDao.getOrgSettingList(orgSettingVo.getBranchCode(), orgSettingVo.getHospitalCode());
            log.info("【组织配置信息列表无method查询】, BranchCode=" + orgSettingVo.getBranchCode() +" HospitalCode=" + orgSettingVo.getHospitalCode() + ",查询结果list=" + JsonUtils.toJsonString(list));
            //如果根据分院查询不到信息，则用总院去查询
            if(list != null && list.size() == 0){
                log.info("【组织配置信息列表无method查询】, 根据分院查询不到信息, 开始往总院查询");
                list = orgSettingDao.getOrgSettingList(orgSettingVo.getHospitalCode(), orgSettingVo.getHospitalCode());
                log.info("【组织配置信息列表无method查询】, HospitalCode=" + orgSettingVo.getHospitalCode() + ",查询结果list=" + JsonUtils.toJsonString(list));
            }
        }

        return list;
    }

    /**
     * 组织配置信息列表查询(对外接口)
     * @param vo
     * @return
     * @author CJun
     */
    public ResCommon<List<OrgSettingVoResponse>> getOrgSettingList(OrgSettingVo vo) {

        //定义返回结果
        ResCommon<List<OrgSettingVoResponse>> resCommon = new ResCommon();

        //组装查询参数
        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("methodCode", vo.getMethodCode());
        dataMap.put("hospitalCode", vo.getHospitalCode());
        dataMap.put("branchCode", vo.getBranchCode());
        dataMap.put("sessionId", vo.getSessionId());

        Response response = listOrgsetting(JsonUtils.toJsonString(dataMap));//BaseService.callUnderlineFromInternal("",
//                "yyt.base.org.setting.list", JsonUtils.toJsonString(dataMap));


        List<OrgSettingVoResponse> list = JsonUtils.parseArray(response.getResult(), OrgSettingVoResponse.class);

        resCommon.setResult(list);
        resCommon.setResultCodeAndMessage(response.getResultCode(),response.getResultMessage());
        return resCommon;
    }

/**
     * 新增组织信息
     * @param data
     * @return
     */
    public ResponseObject addOrg(String data) {
        ResponseObject response = new ResponseObject();
        try {
            log.info("addOrg ==》新增组织信息开始");
            Org orgVo = JsonUtils.parseObject(data,Org.class);
            //查询是否存在相同编号的组织信息
            Org orgCheck = new Org();
            orgCheck.setOrgCode(orgVo.getOrgCode());
            List<Org> list = orgDao.select(orgCheck);
            if(list != null && list.size() > 0){
                if(!list.get(0).getId().equals(orgVo.getId())){
                    log.info("要新增的医院之前已经存在直接返回即可");
                    response.setResultCodeAndMessageAndResult("0","成功",list.get(0));
                    return response;
                }
            }

            orgVo.setId(PKGenerator.generateId());
            orgVo.setCreatedTime(simpleDateFormat.format(new Date()));
            orgVo.setUpdateTime(simpleDateFormat.format(new Date()));

            orgDao.insert(orgVo);
            response.setResultCodeAndMessageAndResult("0","成功",orgVo);
            log.info("addOrg ==》新增组织信息结束");
            return response;
        }catch (Exception e){
            log.error("新增组织信息失败:",e);
             response.setResultCodeAndMessage("-1","新增组织信息失败");
            return response;
        }
    }

    /**
     * 根据应用编码查询医院列表
     * yyt.base.org.by.platform.org.app.code.get
     * @param data
     * @return
     */
    public Response getOrgByPlatformOrgAppCode(String data) {
        Response response = new Response();
        Map<String,Object>  map = JsonUtils.parseObject(data, Map.class);
        if(map == null || !map.containsKey("app_code")){
            response.setResultCodeAndMessage("1001","输入参数有误，app_code不能为空");
        }
        List<Org> orgs ;
        if("all".equals(map.get("app_code"))){
            //查询全部医院
            Org allQuery = new Org();
            allQuery.setOrgType((short) 1);
            orgs = orgDao.select(allQuery);
        }else {
            orgs = orgDao.selectByPlatformOrgAppCode((String) map.get("app_code"));
        }
        List<HospitalOutVo> hospitalList = new ArrayList<>();
        for(Org org : orgs){
            HospitalOutVo hos = new HospitalOutVo();
            hos.setHospitalCode(org.getOrgCode());
            hos.setHospitalName(org.getOrgName());
            hos.setProvinceName(org.getProvinceName());
            hos.setCityName(org.getCityName());
            hos.setAreaName(org.getAreaName());
            hos.setAddress(org.getAddress());

            Org parent = new Org();
            parent.setOrgType((short) 2);
            parent.setParentId(org.getId());
            List<Org> subOrgs = orgDao.select(parent);
            if(subOrgs != null && subOrgs.size() > 0){
                List<BranchOutVo> branchOutVos = new ArrayList<>();
                for(Org subOrg :subOrgs){
                    BranchOutVo branch = new BranchOutVo();
                    branch.setBranchCode(subOrg.getOrgCode());
                    branch.setBranchName(subOrg.getOrgName());
                    branch.setProvinceName(subOrg.getProvinceName());
                    branch.setCityName(subOrg.getCityName());
                    branch.setAreaName(subOrg.getAreaName());
                    branch.setAddress(subOrg.getAddress());
                    branchOutVos.add(branch);
                }
                hos.setBranchList(branchOutVos);
            }
            hospitalList.add(hos);
        }
        response.setResult(JsonUtils.toJsonString(hospitalList));
        response.setResultCodeAndMessage("0", "查询成功!");


        return response;

    }
}
